package org.as.sdg.builder;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;

import org.as.sdg.beans.NavigationTreeNode;
import org.as.sdg.objs.Application;
import org.as.sdg.objs.Navigation;
import org.as.sdg.objs.NavigationDefault;
import org.as.sdg.objs.Node;

@SuppressWarnings("serial")
public class ApplicationBuilder implements Serializable {
	private Application application;

	public ApplicationBuilder() {
		dummy();
	}

	private void dummy() {
		application = new Application();
		Navigation navigation = new Navigation();
		List<Node> navigationNodes = new ArrayList<Node>();
		List<Node> leaves = new ArrayList<Node>();
		navigation.setNode(navigationNodes);
		application.setNavigation(navigation);

		/**
		 * dramas
		 */
		Node node = new Node();
		node.setId("dramas");
		node.setNode(leaves);
		node.setLabel("Gundam Drama Series");
		node.setExpanded(true);
		node.setLeaf(false);
		node.setLink(false);
		navigationNodes.add(node);
		navigation.setNavigationDefault(new NavigationDefault(node));
		Node leaf = new Node();
		leaf.setId("0079");
		leaf.setLabel("Gundam 0079 One year war");
		leaf.setLeaf(true);
		leaf.setExpanded(false);
		leaf.setLink(true);
		leaves.add(leaf);

		leaf = new Node();
		leaf.setId("0080");
		leaf.setLabel("Gundam 0080 War in the Pocket");
		leaf.setLeaf(true);
		leaf.setExpanded(false);
		leaf.setLink(true);
		leaves.add(leaf);

		/**
		 * Maintenance
		 */
		leaves = new ArrayList<Node>();
		node = new Node();
		node.setId("maintenance");
		node.setNode(leaves);
		node.setLabel("G Maintenance");
		node.setExpanded(true);
		node.setLeaf(false);
		node.setLink(false);
		navigationNodes.add(node);

		leaf = new Node();
		leaf.setId("history");
		leaf.setLabel("Black History");
		leaf.setLeaf(true);
		leaf.setExpanded(false);
		leaf.setLink(true);
		leaves.add(leaf);

		leaf = new Node();
		leaf.setId("config");
		leaf.setLabel("G Config");
		leaf.setLeaf(true);
		leaf.setExpanded(false);
		leaf.setLink(true);
		leaves.add(leaf);

	}

	public Application getApplicationStructure() {
		return application;
	}

	public Node getNode(String nodeId) {
		return nodeSearch(application.getNavigation().getNode(), nodeId);
	}

	private Node nodeSearch(List<Node> nodes, String nodeId) {
		for (Node node : nodes) {
			if (node.getId().equals(nodeId)) {
				return node;
			} else if (node.getNode() != null && nodes.size() > 0) {
				Node foundNode = nodeSearch(node.getNode(), nodeId);
				if (foundNode != null) {
					return foundNode;
				}
			}
		}
		return null;
	}

	public DefaultTreeModel getChildNodeTree(String nodeId) {
		Node parentNode = nodeSearch(application.getNavigation().getNode(),
				nodeId);
		// if we have a node build up our tree.
		if (parentNode != null) {
			// create root node, which will be hidden by component attribute
			// settings.
			DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode();
			NavigationTreeNode userObject = new NavigationTreeNode(rootNode);
			userObject.setText("rootNode");
			userObject.setExpanded(true);
			rootNode.setUserObject(userObject);

			// build a tree based on child nodes of parentNode.
			buildChildNodes(rootNode, parentNode.getNode());
			return new DefaultTreeModel(rootNode);
		}
		return null;
	}

	private void buildChildNodes(DefaultMutableTreeNode parentNode,
			List<Node> childNodes) {

		DefaultMutableTreeNode treeNode;
		NavigationTreeNode navNode;

		for (Node node : childNodes) {
			treeNode = new DefaultMutableTreeNode();
			navNode = new NavigationTreeNode(treeNode);
			navNode.setText(node.getLabel());
			navNode.setNodeId(node.getId());
			navNode.setExpanded(node.isExpanded());
			treeNode.setUserObject(navNode);
			navNode.setLeaf(node.isLeaf());
			parentNode.add(treeNode);

			if (node.getNode() != null && node.getNode().size() > 0) {
				buildChildNodes(treeNode, node.getNode());
			}
		}
	}
	
	public Node getDefaultNode() {
        return application.getNavigation()
                .getNavigationDefault().getNavigationNode();
    }
}
